<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Qiankun 微前端架构模拟实例</title>
    <!-- Tailwind CSS -->
    <script src="https://cdn.tailwindcss.com"></script>
    <!-- React -->
    <script src="https://unpkg.com/react@18/umd/react.development.js"></script>
    <script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
    <!-- Vue 3 -->
    <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
    <!-- Babel -->
    <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
    <style>
        .subapp-container {
            min-height: 300px;
            transition: all 0.3s ease-in-out;
        }
    </style>
</head>
<body class="bg-gray-100 text-gray-800 font-sans p-4 sm:p-8">
    <div id="root"></div>

    <!-- Vue 子应用的模板 -->
    <template id="vue-template">
        <div class="p-6 bg-green-50 border-2 border-dashed border-green-500 rounded-lg">
            <h2 class="text-xl font-bold text-green-800 mb-2">Vue 数据运营子应用</h2>
            <p class="text-sm text-gray-600 mb-4">我是一个独立的 Vue 应用，运行在 Qiankun 的沙箱中。</p>
            <div class="bg-white p-4 rounded shadow-sm">
                <p>从主应用接收到的用户信息: <strong class="text-green-600">{{ user.name }} ({{ user.role }})</strong></p>
                <p class="mt-2">我的内部状态 (计数器): {{ count }}</p>
                <button @click="count++" class="mt-4 bg-green-500 text-white font-bold py-2 px-4 rounded hover:bg-green-600">
                    增加 Vue 内部计数
                </button>
            </div>
        </div>
    </template>

    <script type="text/babel">
        const { useState, useEffect, useRef } = React;
        const { createApp } = Vue;

        //============================================
        // 1. 模拟的子应用实例
        //============================================

        // --- React 子应用: 办件派发 ---
        const ReactSubApp = ({ globalState }) => {
            const [internalCount, setInternalCount] = useState(0);
            return (
                <div className="p-6 bg-blue-50 border-2 border-dashed border-blue-500 rounded-lg">
                    <h2 className="text-xl font-bold text-blue-800 mb-2">React 办件派发子应用</h2>
                    <p className="text-sm text-gray-600 mb-4">我是一个独立的 React 应用，同样运行在沙箱中。</p>
                    <div className="bg-white p-4 rounded shadow-sm">
                        <p>从主应用接收到的用户信息: <strong className="text-blue-600">{globalState.user.name} ({globalState.user.role})</strong></p>
                         <p className="mt-2">我的内部状态 (计数器): {internalCount}</p>
                        <button onClick={() => setInternalCount(c => c + 1)} className="mt-4 bg-blue-500 text-white font-bold py-2 px-4 rounded hover:bg-blue-600">
                           增加 React 内部计数
                        </button>
                    </div>
                </div>
            );
        };

        // --- Vue 子应用: 数据运营 ---
        const VueSubApp = {
            template: '#vue-template',
            props: ['globalState'],
            data() {
                return {
                    count: 0,
                    user: this.globalState.user || { name: '未知', role: '未知' }
                }
            },
        };
        
        //============================================
        // 2. 模拟 Qiankun 的核心机制
        //============================================
        const microApps = [
            {
                name: 'reactApp',
                activeRule: '/dispatch',
                mount: (container, props) => {
                    console.log('[Qiankun-sim] Mounting reactApp with props:', props);
                    const root = ReactDOM.createRoot(container);
                    // 保存 root 实例以便卸载
                    container._reactRoot = root; 
                    root.render(<ReactSubApp {...props} />);
                },
                unmount: (container) => {
                    console.log('[Qiankun-sim] Unmounting reactApp');
                    if(container._reactRoot) {
                        container._reactRoot.unmount();
                        delete container._reactRoot;
                    }
                },
            },
            {
                name: 'vueApp',
                activeRule: '/operation',
                mount: (container, props) => {
                    console.log('[Qiankun-sim] Mounting vueApp with props:', props);
                    const app = createApp(VueSubApp, { globalState: props.globalState });
                    // 保存 app 实例以便卸载
                    container._vueApp = app;
                    app.mount(container);
                },
                unmount: (container) => {
                    console.log('[Qiankun-sim] Unmounting vueApp');
                    if (container._vueApp) {
                        container._vueApp.unmount();
                        delete container._vueApp;
                    }
                },
            }
        ];

        let currentApp = null;

        function loadMicroApp(name, container, props) {
            const app = microApps.find(app => app.name === name);
            if (!app) {
                console.error(`App ${name} not found.`);
                return;
            }

            // 先卸载当前应用
            if (currentApp && currentApp.unmount) {
                // 清空容器，为下一个应用做准备
                const currentContainer = document.querySelector('#subapp-container');
                currentApp.unmount(currentContainer);
                currentContainer.innerHTML = '';
            }
            
            // 加载并挂载新应用
            app.mount(container, props);
            currentApp = app;
        }

        //============================================
        // 3. 主应用 (基座)
        //============================================
        const HostApp = () => {
            const containerRef = useRef(null);
            const [activeApp, setActiveApp] = useState(null);
            
            // 模拟主应用的全局状态
            const [globalState, setGlobalState] = useState({
                user: { name: 'Admin', role: '超级管理员' },
            });
            
            const handleLoadApp = (appName) => {
                if(appName === activeApp) return;

                setActiveApp(appName);
                loadMicroApp(appName, containerRef.current, { globalState });
            };

            return (
                <div className="p-8 bg-white rounded-xl shadow-lg">
                    <div className="text-center">
                        <h1 className="text-3xl font-bold text-gray-800">市民热线后台管理系统 (主应用基座)</h1>
                        <p className="mt-2 text-gray-500">当前登录用户: {globalState.user.name}</p>
                    </div>

                    <div className="my-8 flex justify-center space-x-4">
                        <button 
                            onClick={() => handleLoadApp('reactApp')}
                            className={`px-6 py-3 font-semibold rounded-lg shadow-md transition-all ${activeApp === 'reactApp' ? 'bg-indigo-600 text-white' : 'bg-white hover:bg-indigo-50'}`}
                        >
                            办件派发 (React)
                        </button>
                        <button 
                            onClick={() => handleLoadApp('vueApp')}
                             className={`px-6 py-3 font-semibold rounded-lg shadow-md transition-all ${activeApp === 'vueApp' ? 'bg-indigo-600 text-white' : 'bg-white hover:bg-indigo-50'}`}
                        >
                            数据运营 (Vue)
                        </button>
                    </div>

                    <div className="mt-4 p-6 bg-gray-50 rounded-lg">
                        <h2 className="text-lg font-semibold text-center text-gray-700 mb-4">子应用渲染容器</h2>
                        <div id="subapp-container" ref={containerRef} className="subapp-container">
                            {!activeApp && <p className="text-center text-gray-400 p-10">请选择一个子应用进行加载</p>}
                        </div>
                    </div>
                </div>
            );
        };

        const root = ReactDOM.createRoot(document.getElementById('root'));
        root.render(<HostApp />);
    </script>
</body>
</html>
